package de.unibi.comet.ac;

import java.util.List;
import java.util.Collections;

import de.unibi.comet.util.Log;

/**
 * Provides various kinds of resources for a set of strings in a lazy manner.
 */
public class StringSetProvider {
	private List<String> stringList;
	private int totalLength;
	private int longestString;
	
	private String joinedString;
	private String reverseJoinedString;
	
	private SuffixStructure suffixStructure;
	private SuffixStructure reverseSuffixStructure;
	
	public StringSetProvider(List<String> l) {
		stringList=l;
		joinedString=null;
		reverseJoinedString=null;
		suffixStructure=null;
		reverseSuffixStructure=null;
		
		Log.getInstance().startTimer();
		Collections.sort(stringList);
		totalLength = 1;
		longestString = 0;
		for (int i=stringList.size()-1; i>=0; i--) {
			totalLength+=stringList.get(i).length()+1;
			if (stringList.get(i).length()>longestString) {
				longestString=stringList.get(i).length();
			}
		}
		Log.getInstance().stopTimer("ResourceProvider: sort list");
	}
	
	public SuffixStructure getSuffixStructure() {
		if (suffixStructure==null) {
			Log.getInstance().startTimer();
			EnhancedSuffixArray esa = new EnhancedSuffixArray();
			esa.build(getJoinedString());
			suffixStructure = esa;
			Log.getInstance().stopTimer("ResourceProvider: build enhanced suffix array");
		}
		return suffixStructure;
	}

	public SuffixStructure getReverseSuffixStructure() {
		if (reverseSuffixStructure==null) {
			Log.getInstance().startTimer();
			EnhancedSuffixArray esa = new EnhancedSuffixArray();
			esa.build(getReverseJoinedString());
			reverseSuffixStructure = esa;
			Log.getInstance().stopTimer("ResourceProvider: build reverse enhanced suffix array");
		}
		return reverseSuffixStructure;
	}

	public String getJoinedString() {
		if (joinedString!=null) return joinedString;
		Log.getInstance().startTimer();
		StringBuffer s = new StringBuffer(totalLength);
		s.append("$");
		for (String s1 : stringList) {
			for (int j=0; j<s1.length(); j++) {
				s.append(s1.charAt(j));
			}
			s.append('$');
		}
		joinedString=s.toString();
		Log.getInstance().stopTimer("ResourceProvider: generate joinedString");
		return joinedString;
	}
	
	public String getReverseJoinedString() {
		if (reverseJoinedString!=null) return reverseJoinedString;
		
		Log.getInstance().startTimer();
		StringBuffer s_rev = new StringBuffer(totalLength);
		s_rev.append("$");
		for (int i=stringList.size()-1; i>=0; i--) {
			for (int j=stringList.get(i).length()-1; j>=0; j--) {
				s_rev.append(stringList.get(i).charAt(j));
			}
			s_rev.append('$');
		}
		reverseJoinedString=s_rev.toString();
		Log.getInstance().stopTimer("ResourceProvider: generate reverseJoinedString");
		return reverseJoinedString;
	}
	
	public int getStringCount() {
		return stringList.size();
	}
	
	public int getTotalLength(boolean with_seperators) {
		return totalLength-(with_seperators?0:stringList.size()+1);
	}

	public int getTotalLength() {
		return getTotalLength(true);
	}

	public List<String> getList() {
		return stringList;
	}

	public int getLongestString() {
		return longestString;
	}
}
